package cn.thoughtworks.school.services;

import cn.thoughtworks.school.entities.Task;
import cn.thoughtworks.school.entities.vo.TaskHistoryVo;
import cn.thoughtworks.school.repositories.TaskDiffRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static cn.thoughtworks.school.entities.Operation.COPY;
import static cn.thoughtworks.school.entities.Operation.CREATE;

@Service
public class TaskDiffService {
    @Autowired
    private TaskDiffRepository taskDiffRepository;
    @Autowired
    private UserCenterService userCenterService;
    @Autowired
    private AssignmentDiffService assignmentDiffService;

    public void updateTaskNotification(Map data) {
        Task task = Task.build(data);
        updateTaskFromId(task);
        taskDiffRepository.save(task);
    }

    public void moveTaskNotification(List<Map> datas) {
        taskDiffRepository.saveAll(datas.stream().map(Task::build).collect(Collectors.toList()));
    }

    private void updateTaskFromId(Task task) {
        if (Objects.equals(CREATE, task.getOperation()) || Objects.equals(COPY, task.getOperation())) {
            return;
        }
        Long fromId = taskDiffRepository.findFirst1ByTaskIdOrderByIdDesc(task.getTaskId()).getFromId();
        task.setFromId(fromId);
    }

    public List<Task> getLatestTasksByTopicsId(List<Long> topicsId) {
        return topicsId.isEmpty()
            ? new ArrayList<>()
            : taskDiffRepository.findFirst1ByIdAndProgramIdInOrderByTopicsIdDesc(topicsId);
    }

    public List<TaskHistoryVo> getTaskHistory(Long taskId) {
        List<Task> tasks = taskDiffRepository.findAllByTaskIdOrderByIdDesc(taskId);
        List<Long> ids = tasks.stream()
            .map(Task::getOperatorId)
            .collect(Collectors.toList());
        assignmentDiffService.fillAssignmentsToTasks(tasks);
        List<Map> users = userCenterService.getUsersByIds(ids);
        return mergeTasksAndUsers(tasks, users);
    }

    private List<TaskHistoryVo> mergeTasksAndUsers(List<Task> tasks, List<Map> users) {
        return tasks.stream()
            .map(task -> {
                String username = users.stream()
                    .filter(user -> Objects.equals(Long.parseLong(user.get("id").toString()), task.getOperatorId()))
                    .findFirst().orElse(new HashMap())
                    .get("username").toString();

                return TaskHistoryVo.build(task, username);
            }).collect(Collectors.toList());
    }

    public Task getLatestTaskById(long taskId) {
        return taskDiffRepository.findFirst1ByTaskIdOrderByIdDesc(taskId);
    }
}
